package cn.lg.soar.redis.manager;

import cn.lg.soar.common.data.msg.I18n;
import cn.lg.soar.common.exceptions.DebounceException;
import cn.lg.soar.core.manager.DebounceManager;
import jakarta.annotation.Resource;
import org.redisson.Redisson;
import org.redisson.api.RLock;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

public class RedisDebounceManager implements DebounceManager {

    @Resource
    private Redisson redisson;

    @Override
    public <T> T lock(String lockName, Supplier<T> handler) {
        RLock lock = redisson.getLock(lockName);
        try {
            if (lock.tryLock(0, -1, TimeUnit.MILLISECONDS)) {
                return handler.get();
            }
            throw new DebounceException(I18n.build("请勿重复执行", lockName));
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    @Override
    public void lock(String lockName, Runnable handler) {
        RLock lock = redisson.getLock(lockName);
        try {
            if (lock.tryLock(0, -1, TimeUnit.MILLISECONDS)) {
                handler.run();
            } else {
                throw new DebounceException(I18n.build("请勿重复执行", lockName));
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

}
